package org.spider.api.context;

import lombok.Data;
import lombok.EqualsAndHashCode;
import org.spider.api.concurrent.SpiderThreadPoolExecutorManager.SubThreadPool;
import org.spider.api.domain.utilDomain.SpiderOutput;
import org.springframework.beans.factory.annotation.Value;

import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * <p>保存spider上下文信息，一个flow就对应一个spiderContext<br>
 * 每次运行一个flow，都会生成一个SpiderContext对象，因此需要记录flowID，<br>
 * 以及这个flow对应的线程池。这一个flow其实就是一次任务，所有和任务相关的<br>
 * 重要信息都被SpiderContext维护
 * </p>
 * <p>
 *     爬虫任务会有数据的输出，结果应该保存到List中<br>
 *     爬虫任务会有日志的实时输出，应该有对应的方法<br>
 * </p>
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class SpiderContext extends ConcurrentHashMap<String,Object> {
    // context的id,每次任务都会创建一个context，如果要控制任务运行的状态，例如暂停，恢复，结束，那么得利用这个id
    private String id = UUID.randomUUID().toString().replace("-", "");
    private String flowId;
    private SubThreadPool threadPool;
    private volatile boolean isRunning=true;
    private LinkedBlockingQueue<Future<?>> futureQueue=new LinkedBlockingQueue<>();
    // 还应该维护一个cookie上下文，因为该任务的cookie不应该与其他任务共享
    private CookieContext cookieContext=new CookieContext();
    @Value("${spider.job.workspace}")
    private String workspace;

    // 以下泛型方法可以根据defaultValue的类型来确定返回值类型
    // 同样可以根据引用变量的类型来转化类型
    public <T> T get(String key){
        return (T) super.get(key);
    }

    public <T> T get(String key,T defaultValue){
        T value = this.get(key);
        return value == null ? defaultValue : value;
    }

    public void addOutput(SpiderOutput output){
    }

    public void pause(String nodeId,String event,String key,Object value){}

    public void resume(){}

    public void stop(){}
}


